package xyz.ssf.cloud.common.interceptor;

import com.alibaba.fastjson2.JSON;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import xyz.ssf.cloud.common.core.domain.R;
import xyz.ssf.cloud.common.utils.JwtUtil;
import xyz.ssf.cloud.common.utils.RedisUtil;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * JWT认证拦截器
 * 
 * @author ssf
 */
@Component
public class JwtAuthInterceptor implements HandlerInterceptor {
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private RedisUtil redisUtil;
    
    // 登录用户Redis前缀
    private static final String LOGIN_TOKEN_KEY = "login_tokens:";
    
    // 不需要验证的路径
    private static final String[] EXCLUDE_PATHS = {
        "/user/login",
        "/user/captcha",
        "/auth/login",
        "/auth/captcha"
    };

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果不是映射到方法，直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        
        // 判断请求路径是否需要验证
        String requestURI = request.getRequestURI();
        System.out.println("请求路径: " + requestURI);
        for (String path : EXCLUDE_PATHS) {
            if (requestURI.contains(path)) {
                System.out.println("排除路径，无需验证: " + path);
                return true;
            }
        }
        
        // 获取请求头中的token
        String token = request.getHeader(jwtUtil.getHeader());
        
        // 如果token为空，尝试从Authorization头获取
        if (StringUtils.isBlank(token)) {
            token = request.getHeader("Authorization");
            System.out.println("尝试从Authorization获取token: " + token);
        }
        
        System.out.println("获取到的Token: " + token);
        if (StringUtils.isBlank(token)) {
            // 未提供token
            System.out.println("未提供token");
            responseError(response, R.UNAUTHORIZED, "未提供token");
            return false;
        }
        
        // 处理 Bearer 前缀
        String tokenValue = token;
        if (token.startsWith("Bearer ")) {
            tokenValue = token.substring(7);
            System.out.println("移除了Bearer前缀，处理后的token: " + tokenValue);
        }
        
        // 验证token有效性
        if (!jwtUtil.validateToken(tokenValue)) {
            // token已过期或无效
            System.out.println("token已过期或无效");
            responseError(response, R.UNAUTHORIZED, "token已过期或无效");
            return false;
        }
        
        // 从Redis获取用户信息，使用不带前缀的token作为键的一部分
        String userKey = LOGIN_TOKEN_KEY + tokenValue;
        System.out.println("查询Redis键: " + userKey);
        Object loginUser = redisUtil.getCacheObject(userKey);
        System.out.println("Redis中的用户信息: " + (loginUser != null ? "存在" : "不存在"));
        
        if (loginUser == null) {
            // 登录状态已过期
            System.out.println("登录状态已过期");
            responseError(response, R.UNAUTHORIZED, "登录状态已过期");
            return false;
        }
        
        System.out.println("验证通过");
        return true;
    }
    
    /**
     * 响应错误信息
     * 
     * @param response 响应对象
     * @param code 状态码
     * @param message 错误信息
     */
    private void responseError(HttpServletResponse response, int code, String message) throws IOException {
        response.setStatus(200);
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        PrintWriter writer = response.getWriter();
        writer.write(JSON.toJSONString(R.error(code, message)));
        writer.flush();
    }
}